package cn.mothin.frame.help;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.mothin.frame.core.annotation.Module;
import cn.mothin.frame.core.annotation.NeedLogon;
import cn.mothin.frame.core.annotation.NeedModule;
import cn.mothin.frame.core.annotation.NeedPermission;
import cn.mothin.frame.core.annotation.NeedPermissionAs;
import cn.mothin.frame.core.annotation.NeedPermissionTemplate;
import cn.mothin.frame.core.annotation.NeedSuper;
import cn.mothin.frame.core.base.BaseService;
import cn.mothin.frame.core.interfaces.ILoginUser;
import cn.mothin.frame.core.interfaces.IPermissionRobot;
import cn.mothin.frame.core.interfaces.ISqlHelper;
import cn.mothin.frame.core.interfaces.vo.IViewObject;

@Service
public class PermissionRobot extends BaseService implements IPermissionRobot {
	@Autowired
	private ActionScanner actionScanner;
	@Autowired
	private ISqlHelper sqlHelper;
	
	private int checkPermission(Class<?> c, Method method, IViewObject vo,
			String action) {
		ILoginUser loginUser = getLoginUser();
		if (loginUser == null) {
			return 1;
		}
		if (method.isAnnotationPresent(NeedLogon.class)) {
			return 0;
		}

		if (loginUser.isSuperUser()) {
			return 0;
		}

		String sql = "SELECT COUNT(id) FROM role_module_permission WHERE moduleItemId=? AND systemRoleId IN (SELECT systemRoleId FROM system_user_role WHERE systemUserId=?)";
		if (method.isAnnotationPresent(NeedModule.class)) {
			Module module = c.getAnnotation(Module.class);
			if (sqlHelper.queryCount(sql, module.id(), loginUser.getId()) > 0) {
				return 0;
			}
		} else if (method.isAnnotationPresent(NeedPermission.class)) {
			NeedPermission needPermission = method
					.getAnnotation(NeedPermission.class);
			if (sqlHelper.queryCount(sql, needPermission.id(),
					loginUser.getId()) > 0) {
				return 0;
			}
		} else if (method.isAnnotationPresent(NeedPermissionAs.class)) {
			NeedPermissionAs needPermissionAs = method
					.getAnnotation(NeedPermissionAs.class);
			try {
				Method newMethod = c
						.getDeclaredMethod(needPermissionAs.value());
				if (newMethod.isAnnotationPresent(NeedPermission.class)) {
					NeedPermission needPermission = newMethod
							.getAnnotation(NeedPermission.class);
					if (sqlHelper.queryCount(sql, needPermission.id(),
							loginUser.getId()) > 0) {
						return 0;
					}
				} else if (newMethod
						.isAnnotationPresent(NeedPermissionTemplate.class)) {
					NeedPermissionTemplate needPermissionTemplate = newMethod
							.getAnnotation(NeedPermissionTemplate.class);
					if (sqlHelper.queryCount(sql, needPermissionTemplate.id(),
							loginUser.getId()) > 0) {
						return 0;
					}
				}
			} catch (Exception e) {
			}
		} else if (method.isAnnotationPresent(NeedPermissionTemplate.class)) {
			NeedPermissionTemplate needPermissionTemplate = method
					.getAnnotation(NeedPermissionTemplate.class);
			if (sqlHelper.queryCount(sql, needPermissionTemplate.id(),
					loginUser.getId()) > 0) {
				return 0;
			}
		}
		return 2;
	}

	public boolean needCheckPermission(Method method) {
		if (method.isAnnotationPresent(NeedPermission.class)) {
			return true;
		}
		if (method.isAnnotationPresent(NeedPermissionAs.class)) {
			return true;
		}
		if (method.isAnnotationPresent(NeedLogon.class)) {
			return true;
		}
		if (method.isAnnotationPresent(NeedModule.class)) {
			return true;
		}
		if (method.isAnnotationPresent(NeedSuper.class)) {
			return true;
		}
		if (method.isAnnotationPresent(NeedPermissionTemplate.class)) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param jp
	 * @param c
	 * @param method
	 * @return 0：权限检测无问题； 1：需要登录； 2：无访问权限；
	 */
	public int checkPermission(Class<?> c, Method method, IViewObject vo) {
		return checkPermission(c, method, vo, null);
	}

	public int checkPermission(String action) {
		if (actionScanner == null) {
			return 2;
		}

		String cn = actionScanner.getClassName(action);
		String mn = actionScanner.getMethodName(action);

		try {
			Class<?> c = Class.forName(cn);
			Method method = c.getMethod(mn);
			if (!needCheckPermission(method)) {
				return 0;
			}
			return checkPermission(c, method, null, action);
		} catch (Exception e) {
			// logger.error(e);
		}
		return 2;
	}

	public int checkPermission(String className, String methodName,
			IViewObject vo) {
		try {
			Class<?> c = Class.forName(className);
			Method method = c.getMethod(methodName);
			if (!needCheckPermission(method)) {
				return 0;
			}
			return checkPermission(c, method, vo);
		} catch (Exception e) {
			// logger.error(e);
		}
		return 2;
	}
}
